package com.company.cloud.goodsrestservice.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.company.cloud.goodsrestservice.core.Result;
import com.company.cloud.goodsrestservice.core.ResultGenerator;
import com.company.cloud.goodsrestservice.model.*;
import com.company.cloud.goodsrestservice.service.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import java.util.List;


/**
* Created by reabout on 2018/03/05.
*/
@RestController
@RequestMapping("/sku")
public class SkuController {
    private final Logger log = LoggerFactory.getLogger(SkuController.class);

    @Resource
    private SkuService skuService;
    @Resource
    private BrandService brandService;
    @Resource
    private CategoryService categoryService;
    @Resource
    private ColorService colorService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private SkuCommonService skuCommonService;
    @Resource
    private StockService stockService;
    @Resource
    private SkuLocationService skuLocationService;
    @Resource
    private SkuOrderRelService skuOrderRelService;
    @Resource
    private OrderService orderService;

    //更新库存
    @GetMapping("/updateStock")
    public Result updateStock(
            @RequestParam(value="materialNumber") String materialNumber, //物料码
            @RequestParam(value="stock") Integer stock,   //库存
            @RequestParam(value="locationId") Integer locationId   //货位ID
    		) {
    	if(stock < 0) {
        	return ResultGenerator.genFailResult("Stock format error: " + stock.toString());
        }
        SkuCommon sku = skuCommonService.findBy("skuMaterialNumber", materialNumber);
    	if (sku == null) {
            return ResultGenerator.genFailResult("Invalid materialNumber");
        }
        SkuLocation stockLocation = skuLocationService.findBy("stockLocationId", locationId);
    	String location;
    	if (stockLocation == null) {
//    	    locationId = 0;
//    	    location = "";
            return ResultGenerator.genFailResult("Invalid locationId");
        } else {
    	    location = stockLocation.getStockLocation() + "_" + stockLocation.getStockWarehouse();
//            location = stockLocation.getStockLocation();
        }
        Stock sku_stock = stockService.chkInsert(sku.getSkuId(), location, locationId, "", stock);
//    	Integer result = skuService.updateStock(materialNumber,stock,locationId );
        if(sku_stock == null) {
        	return ResultGenerator.genFailResult("No rows affected");
        }else {
        	return ResultGenerator.genSuccessResult(sku_stock);
        }
   	
    }
    //通过物料码获取相关SKU
    @GetMapping("/find")
    public Result detail(@RequestParam() String materialNumber) {
        List<Sku> list = skuService.getSkuByMaterialNumber(materialNumber);
        if(list == null) {
        	return ResultGenerator.genSuccessResult();
        }else {
        	return ResultGenerator.genSuccessResult(list);
        }
    }
    //通过时间段获取SKU List
    @GetMapping("/list")
    public Result list(
            @RequestParam(value="startTime") Long startTime, //开始时间
            @RequestParam(value="endTime") Long endTime,   //结束时间
            @RequestParam(value="page", defaultValue = "0") Integer page,
            @RequestParam(value="size", defaultValue = "0") Integer size) {
        if(startTime < 0||endTime < 0) {
        	return ResultGenerator.genFailResult("Time format error");
        }
        PageHelper.startPage(page, size);
    	List<Sku> list = skuService.getSkuListByTime(startTime, endTime);
        if(list == null) {
        	return ResultGenerator.genSuccessResult();
        }else {
        	PageInfo pageInfo = new PageInfo(list);
        	return ResultGenerator.genSuccessResult(pageInfo);
        }   
    }

    @GetMapping("/listBySearch")
    public Result listBySearch(@RequestParam String key, @RequestParam Object value,
                               @RequestParam(value="page", defaultValue = "0") Integer page,
                               @RequestParam(value="size", defaultValue = "0") Integer size) {
        List <Sku> list;
        try {
            PageHelper.startPage(page, size);
            if (key.toLowerCase().equals("goodsnumber")) {
                list = skuService.getSkuByGoodsNumber(value.toString());
            } else if (key.toLowerCase().equals("skuname")) {
                list = skuService.getSkuBySkuName(value.toString());
            } else if (key.toLowerCase().equals("materialnumber")) {
                list = skuService.getSkuByMaterialNumber(value.toString());
            } else if (key.toLowerCase().equals("category")) {
                list = skuService.getSkuByCategory(value.toString());
            } else if (key.toLowerCase().equals("orderid")) {
                list = skuService.getSkuByOrderId((int)value);
            } else if (key.toLowerCase().equals("all") & value.toString().toLowerCase().equals("all")) {
                list = skuService.getSkuAll();
            } else if (key.toLowerCase().equals("multiple")) {
                list = skuService.getSkuBySearch(value);
            } else {
                return ResultGenerator.genFailResult("Key error: " + key);
            }
            PageInfo pageInfo = new PageInfo(list);
            return ResultGenerator.genSuccessResult(pageInfo);
        } catch (Exception e) {
            return ResultGenerator.genFailResult("Param error: "+key+"="+value.toString());
        }
    }

    @PostMapping("/listByJson")
    public Result listByJson(@RequestBody JSONObject sku,
                             @RequestParam(value="page", defaultValue = "0") Integer page,
                             @RequestParam(value="size", defaultValue = "0") Integer size) {
        List <Sku> list;
        PageHelper.startPage(page, size);
        list = skuService.getSkuByJson(sku);
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    //通过OrderId获取SKU List
    @GetMapping("/listByOrderId")
    public Result listByOrderId(@RequestParam Integer orderId,
                                @RequestParam(defaultValue = "0") Integer page,
                                @RequestParam(defaultValue = "0") Integer size) {
        PageHelper.startPage(page, size);
        List<Sku> skuList = skuService.getSkuByOrderId(orderId);
        if(skuList==null) {
            return ResultGenerator.genFailResult("不存在相关SKU信息");
        }else {
            PageInfo pageInfo = new PageInfo(skuList);
            return ResultGenerator.genSuccessResult(pageInfo);
        }
    }

    //单行添加SKU
    @PostMapping("/add")
    public Result add(@RequestParam() Integer orderId,
                      @RequestBody DataObject data) {
        Order order = orderService.findById(orderId);
        if (order == null) {
            return ResultGenerator.genFailResult("请先创建SKU订单信息");
        }
        log.info(orderId.toString());
        log.info(JSON.toJSONString(data));
        try {
//            parseGoods(orderId, data);
            newParseGoods(orderId, data);
            return ResultGenerator.genSuccessResult();
        } catch (Exception e) {
            log.error("Error with data {}", JSON.toJSONString(data));
            return ResultGenerator.genFailResult(e.toString());
        }

    }

    //多行添加SKU
    @PostMapping("/addList")
    public Result addList(@RequestParam() Integer orderId,
                          @RequestBody List<DataObject> dataList) {
        Integer count = 0;
        Order order = orderService.findById(orderId);
        if (order == null) {
            return ResultGenerator.genFailResult("请先创建SKU定单信息");
        }
        for  (DataObject data: dataList) {
            try {
                newParseGoods(orderId, data);
            } catch (Exception e) {
                log.error("Error with data {}", data.toString());
                log.error(e.toString());
                continue;
            }
            count++;
        }
        return ResultGenerator.genSuccessResult("total: "+dataList.size()+", success: "+count);
    }

    public void newParseGoods(Integer orderId, DataObject data) {
        String brandName = data.getBrand()==null?"":data.getBrand();
        Brand brand = brandService.chkInsert(brandName);
        if (brand == null) {
            log.warn("Warnning: No brand with data: {}", JSON.toJSONString(data));
        }
        String categoryName = data.getCategory()==null?"":data.getCategory();
        Category category = categoryService.chkInsert(categoryName);
        if (category == null) {
            log.warn("Warnning: No category with data: {}", JSON.toJSONString(data));
        }
        String colorName = data.getColor()==null?"":data.getColor();
        Color color = colorService.chkInsert(colorName);
        if (color == null) {
            log.warn("Warnning: No color with data: {}", JSON.toJSONString(data));
        }

        Float pjd = (float) 0;
        Float pof = (float) 0;
        Float peu = (float) 0;
        Float psu = (float) 0;
        if (data.getPriceJd() != null) {
            pjd = data.getPriceJd();
        }
        if (data.getPriceOffical() != null) {
            pof = data.getPriceOffical();
        }
        if (data.getPriceOfficalEu() != null) {
            peu = data.getPriceOfficalEu();
        }
        if (data.getPriceSupply() != null) {
            psu = data.getPriceSupply();
        }
        Goods goods = goodsService.chkInsert(data.getGoodsNumber(), pjd, pof, peu, psu);
        if (brand != null) {
            goods.setBrandId(brand.getBrandId());
        }
        if (category != null) {
            goods.setCategoryId(category.getCategoryId());
        }
        if (brand != null | category != null) {
            goods.setUpdateTime(System.currentTimeMillis());
            goodsService.update(goods);
        }
        SkuCommon sku = skuCommonService.chkInsert(data.getMaterialNumber(), data.getSkuName(), data.getSkuModel(), data.getStock(), goods.getGoodsId(), color.getColorId(),orderId);
        if (data.getStock() != null) {
            Integer locationId = data.getLocationId() == null ? 0 : data.getLocationId();
            log.warn("SkuLocationId为0");
            String location = data.getStockLocation() == null ? skuLocationService.findById(locationId).getStockLocation() : data.getStockLocation();
            stockService.chkInsert(sku.getSkuId(), location, locationId, data.getCaseNumber(), data.getStock());
        }
    }

    public void parseGoods(Integer orderId, DataObject data) {
        Brand brand = brandService.findBy("brandName", data.getBrand());
        if (brand == null & data.getBrand()!="") {
//                Brand brand = new Brand();
            log.info("New brand {}", data.getBrand());
            brand.setBrandName(data.getBrand());
            brand.setBrandMark("");
            brand.setStatus(2);
//            brand.setCreateTime(System.currentTimeMillis());
            brandService.save(brand);
            brand = brandService.findBy("brandName", data.getBrand());
        }
        Category category = categoryService.findBy("categoryName", data.getCategory());
        if (category == null & data.getCategory()!="") {
            log.info("New category {}", data.getCategory());
            category.setCategoryName(data.getCategory());
            category.setCategoryMark("gom");
            category.setParentId(-1);
            category.setCreateTime(System.currentTimeMillis());
            category.setStatus(2);
            categoryService.save(category);
            category = categoryService.findBy("categoryName", data.getCategory());
        }
        Color color = colorService.findBy("colorName", data.getColor());
        if (color == null & data.getColor() != "") {
            log.info("New color {}", data.getColor());
            color.setColorName(data.getColor());
            color.setStatus(2);
            color = colorService.findBy("colorName", data.getColor());
        }
        Goods goods = goodsService.findBy("goodsNumber", data.getGoodsNumber());
        if (goods == null & data.getGoodsNumber()!="") {
            log.info("New goods {}", data.getGoodsNumber());
            goods.setBrandId(brand.getBrandId());
            goods.setCategoryId(category.getCategoryId());
            goods.setGoodsNumber(data.getGoodsNumber());
            goods.setPriceJd(data.getPriceJd());
            goods.setPriceOffical(data.getPriceOffical());
            goods.setPriceOfficalEu(data.getPriceOfficalEu());
            goods.setPriceSupply(data.getPriceSupply());
            Long now = System.currentTimeMillis();
            goods.setCreateTime(now);
            goods.setUpdateTime(now);
            float ps = data.getPriceSupply();
            float po = data.getPriceOffical();
            if (ps != 0 & po != 0) {
                goods.setGoodsDiscountRate(ps/po);
            } else {
                goods.setGoodsDiscountRate(null);
            }
            goods = goodsService.findBy("goodsNumber", data.getGoodsNumber());
        } else {
//            String gnumber = data.getGoodsNumber();
            Float po = data.getPriceOffical();
            Float poe = data.getPriceOfficalEu();
            Float ps = data.getPriceSupply();
            Float pjd = data.getPriceJd();
            goods.setBrandId(brand.getBrandId());
            goods.setCategoryId(category.getCategoryId());
//            if (gnumber != "") {
//                goods.setGoodsNumber(gnumber);
//            }
            if (po != null) {
                goods.setPriceOffical(po);
            }
            if (poe != null) {
                goods.setPriceOfficalEu(poe);
            }
            if (ps != null) {
                goods.setPriceSupply(ps);
            }
            if (pjd != null) {
                goods.setPriceJd(pjd);
            }
            Long now = System.currentTimeMillis();
            goods.setUpdateTime(now);
            goodsService.update(goods);
        }
        SkuCommon sku = skuCommonService.findBy("skuMaterialNumber", data.getMaterialNumber());
        if (sku == null & data.getMaterialNumber()!="") {
            log.info("New sku_material_number {}", data.getMaterialNumber());
            sku.setGoodsId(goods.getGoodsId());
            sku.setSkuMaterialNumber(data.getMaterialNumber());
            sku.setSkuSource(1);
            sku.setSkuName(data.getSkuName());
            sku.setSkuModel(data.getSkuModel());
            sku.setColorId(color.getColorId());
            sku.setSkuStock(data.getStock());
            Long now = System.currentTimeMillis();
            sku.setCreateTime(now);
            sku.setUpdateTime(now);
            skuCommonService.save(sku);
            sku = skuCommonService.findBy("skuMaterialNumber", data.getMaterialNumber());
            SkuOrderRel skuOrderRel = new SkuOrderRel();
            skuOrderRel.setOrderId(orderId);
            skuOrderRel.setSkuId(sku.getSkuId());
            skuOrderRelService.save(skuOrderRel);
        } else {
            if (data.getSkuName() != "") {
                sku.setSkuName(data.getSkuName());
            }
            sku.setColorId(color.getColorId());
            if (data.getSkuModel() != "") {
                sku.setSkuModel(data.getSkuModel());
            }
            Long now = System.currentTimeMillis();
            sku.setUpdateTime(now);
            skuCommonService.update(sku);
        }

        Condition condition = new Condition(Stock.class);
        condition.setForUpdate(true);
        condition.createCriteria().andEqualTo("skuId", sku.getSkuId()).andEqualTo("stockLocation", data.getStockLocation());
        List<Stock> stocks = stockService.findByCondition(condition);
        if (stocks.isEmpty()) {
            log.info("New stock {}", data.getStockLocation());
            Stock stock = new Stock();
            stock.setSkuId(sku.getSkuId());
            stock.setStockCaseNumber(data.getCaseNumber());
            stock.setStockLocation(data.getStockLocation());
            stock.setStockLocationId(data.getLocationId());
            stock.setStockNumber(data.getStock());
            stockService.save(stock);
        } else {
            Stock stock = stocks.get(0);
            if (data.getCaseNumber() != "") {
                stock.setStockCaseNumber(data.getCaseNumber());
            }
            if (data.getStock() != null) {
                stock.setStockNumber(data.getStock());
            }
            stockService.update(stock);
        }
    }
}
